<template>
  <div :class="['hg-upload-wrap', className]">
    <el-upload ref="uploadFile" v-show="!readonly && limitUploadHideJudge" class="hg-upload-main" :action="action"
      :multiple="multiple" :accept="accept" :limit="limit" :file-list="fileList" :show-file-list="false"
      :on-exceed="onExceed" :before-upload="beforeUpload" :on-success="onUploadSuccess" :on-progress="onProgress"
      :headers="headers" :disabled="disabled" :drag="drag">
      <slot>
        <el-button icon="el-icon-upload">
          上传文件
        </el-button>
      </slot>
      <div slot="tip" class="el-upload-tip" v-if="!!tips">
        {{ tips }}
      </div>
      <div slot="tip" class="el-upload-tip" v-else-if="!!accept">
        文件最大{{ maxSize }}M，格式： {{ accept }}
      </div>
    </el-upload>

    <div class="hg-files-main" v-if="fileList.length">
      <div v-for="(item, i) in fileList" :key="item.filePath" class="form-file-item">
        <div class="item">
          <div v-if="item.type === 'img'" class="img-box">
            <el-image class="img-item" :src="`${downloadUrl + item.filePath}`" :preview-src-list="previewSrcList" />
            <div class="img-url FB1 omit upload-result-color">{{ item.fileName || item.name }}</div>
          </div>
          <div v-else class="media-box omit upload-result-color">
            <a v-if="!item.status || item.status == 'success'" :href="`${downloadUrl + item.filePath}`"
              :download="item.fileName || item.name" target="_blank">{{
                item.fileName || item.name
              }}</a>
            <span v-else>{{ item.fileName || item.name }}</span>
          </div>
          <div class="color-primary el-icon--left  icon_percentage upload-result-color"
            v-show="item.status == 'uploading'">
            <i class="el-icon-loading color-primary  "></i>
            <span> {{ _formatProgress(item.percentage) }} </span>
          </div>
        </div>
        <div class="el-center-icon">
          <i v-if="!disabled && !readonly" class="el-icon-delete el-delete-icon" @click="onRemoveFile(item)" />
        </div>

      </div>
    </div>
  </div>
</template>
<script>
/**
 *
 * todo: 上传进度
 */
import _ from 'lodash'

// 检测图片的正则
const imgReg = /\.png|jpg|jpeg|gif$/i



const mapExtMap = {
  "xls": "application/vnd.ms-excel",
  "xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
  "pdf": "application/pdf",
  "doc": "application/msword",
  "docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
  "zip": "application/zip",
  "mp4": "video/mp4"
}


export default {
  name: 'hg-upload',
  filters: {
    toFixed: function (value) {
      if (!value) return 0
      if (Number.isNaN(Number.parseFloat(value))) return 0
      return Number.parseFloat(value.toFixed(1))
    }
  },
  props: {

    // 最大上传文件大小 单位: m
    maxSize: {
      type: Number,
      default: 10
    },

    className: {
      type: String,
      detault: ''
    },
    action: {
      type: String,
      default() {
        return this.$ex_default_upload_url;
      }
    },
    downloadUrl: {
      type: String,
      default() {
        return this.$ex_default_download_url;
      }
    },
    multiple: {
      type: Boolean,
      default: false
    },
    accept: {
      type: String,
      default: ''
    },
    limitUploadHide: {
      type: Boolean,
      default: false
    },
    limit: {
      type: Number,
    },
    value: {
      type: Array,
      default: () => []
    },

    headers: {
      type: Object,
      default: () => ({})
    },
    disabled: {
      type: Boolean,
      default: false
    },
    drag: {
      type: Boolean,
      default: false
    },
    readonly: {
      type: Boolean,
      default: false
    },
    tips: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      // 自定义的文件列表
      fileList: [],

    }
  },
  computed: {
    previewSrcList() {
      return this.fileList.filter(it => it.type === 'img').map(it => this.downloadUrl + it.filePath)
    },
    limitUploadHideJudge() {
      return this.fileList.length < this.limit || !this.limitUploadHide
    },
  },
  watch: {
    value: {
      handler(newValue) {
        this.setFileList(newValue)
      },
      deep: true
    }
  },
  created() {
    if (this.value) {
      this.reset()
    }
    // 上传成功后, 将结果返回给 value
    // 对返回结果进行节流处理, 减小并发和开销
    if (this.multiple) {
      this.onUploadSuccess = _.debounce(this.updateValues, 500)
    } else {
      this.onUploadSuccess = this.updateValues
    }

    // 针对几种后缀名处理
    // const tmps = []
    // // accept 支持传递点号开头、或者不加点号
    // // .png, jpg
    // // png, pdf, docx
    // this.accept.split(',').forEach(key => {
    //   const mapKey = key.replace(/^\./, '')
    //   if (mapExtMap[mapKey]) {
    //     tmps.push(mapExtMap[mapKey])
    //   } else {
    //     tmps.push(key.match(/^\./) ? key : `.${key}`)
    //   }
    // })

    // this.acceptValues = tmps.join(',')
  },


  methods: {
    reset() {
      this.setFileList(this.value)
    },
    setFileList(list) {
      this.fileList = this.formatFileList(list)
    },
    _formatProgress(tip) {
      return tip ? tip.toFixed(2) + '%' : ''
    },
    onProgress(event, file, fileList) {
      this.fileList = fileList
    },
    beforeUpload(file) {
      if (file.size > (this.maxSize * 1024 * 1024)) {
        this.$message.error('最大上传大小为' + this.maxSize + 'M')
        return false
      }

      return true
    },
    // 批量更新上传的文件
    updateValues(res, file, fileList) {
      if (res.code === 0) {

        let updatefiles = fileList.map(item => (item.response ? item.response.data : item))
        // 过滤掉上传失败的文件
        this.$emit('input', updatefiles)
        this.fileList = updatefiles
      }
      else {
        let index = _.findIndex(fileList, file)
        fileList.splice(index, 1)
        this.$message.error(res.message || '上传失败')
        this.fileList = fileList
      }

    },
    // 格式化文件列表, 图片就展示出来, 其他文件类型就展示名称
    formatFileList(value) {
      const fileList = []
      // 之前有文件只保存了一个链接, 容错一下
      // 未来也可能出现某个字段从文本类型改成了文件类型, 如果出现了这种情况, 直接抛弃之前的值
      if (typeof this.value === 'string') {
        this.value = []
        return fileList
      }
      // 如果没有值
      if (!value || !value.length) {
        return fileList
      }
      value.forEach((item) => {
        if (item.filePath && item.filePath.match(imgReg)) {
          fileList.push({
            ...item,
            type: 'img'
          })
        } else {
          fileList.push({
            ...item,
            type: 'media'
          })
        }
      })
      return fileList
    },
    // 文件超出时给出提示, 多选的时候用得到
    onExceed(files, fileList) {
      this.$message.error(
        `当前限制选择 ${this.limit} 个文件，请先删除后再选择`
      )
    },

    // 删除文件
    onRemoveFile(file) {
      if (file.status == 'ready' || file.status == 'uploading') {
        this.$refs['uploadFile'].abort(file)
        let index = _.findIndex(this.fileList, file)
        this.fileList.splice(index, 1)
      } else {
        let index = _.findIndex(this.fileList, file)
        this.fileList.splice(index, 1)
        this.$emit('input', this.fileList)
      }

    }
  }
}
</script>
<style lang="css" scoped>
.hg-upload-wrap {
  width: 100%;
}

.hg-upload-wrap .hg-upload-main .el-upload-tip {
  padding-top: 6px;
  color: #999;
  font-size: 12px;
}

.hg-upload-wrap .hg-files-main {
  /* padding: 5px 0; */
}

.hg-upload-wrap .form-file-item {

  line-height: 30px;
  transition: all 0.15s;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
}


.hg-upload-wrap .form-file-item .item {
  display: flex;
  flex-direction: row;
  align-items: center;
}


.hg-upload-wrap .form-file-item:not(:last-child) {
  padding-bottom: 4px;
}

.hg-upload-wrap .form-file-item .img-box {
  width: 100%;
  display: flex;
}

.hg-upload-wrap .form-file-item .img-box .img-item {
  width: 30px;
  height: 30px;
  margin-right: 4px;
}

.hg-upload-wrap .form-file-item .img-box .img-url {
  flex: 1;
  font-size: 12px;
}

.hg-upload-wrap .form-file-item .media-box {
  flex: 1;
  line-height: 30px;
  padding: 0 4px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.hg-upload-wrap .form-file-item .el-center-icon {
  display: flex;
  align-items: center;
  justify-content: center;
}

.hg-upload-wrap .form-file-item .el-delete-icon {

  line-height: 30px;
  color: #606266;
  margin: 0 5px;
  visibility: hidden;
  opacity: 0;
  transition: all 0.15s;
  cursor: pointer;
}

.hg-upload-wrap .form-file-item:hover {
  background-color: #f5f7fa;
}

.hg-upload-wrap .form-file-item:hover .el-icon-delete {
  opacity: 1;
  visibility: visible;
}

.upload-result-color {
  color: #3A82D5;
  font-size: 12px;
}


.upload-result-color a {
  color: #3A82D5
}
</style>
